import logging
import smtplib
from email.header import Header
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from typing import List, Union, Literal
import os
import re

class EmailUtils:
    # 服务器地址
    __server = os.getenv('SMTP_SERVER', 'smtp.qq.com')
    # 端口
    __port = int(os.getenv('SMTP_PORT', 465))
    # 用户
    __username = os.getenv('SMTP_USERNAME', '2529023117@qq.com')
    # 校验码
    __code = os.getenv('SMTP_CODE', 'jycuiyloqvdgdjfg')
    # 发件人
    __from_addr = ''
    # 收件人
    __to_addrs = None
    # 邮件引擎
    __stmp = None

    logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')

    def __init__(self, username=__username, code=__code, server=__server, port=__port):
        self.__server = server
        self.__port = port
        self.__username = username
        self.__code = code
        try:
            self.__stmp = smtplib.SMTP_SSL(server, port)
            self.__stmp.login(username, code)
            logging.info("邮箱服务器登录成功")
        except Exception as e:
            logging.error(f"邮箱服务器登录失败！错误：{e}")
            raise e

    # 读取路径上的文件名
    def __handle_file_name(self, file_path: str):
        return os.path.basename(file_path)

    # 判断是否为html
    def __is_html(self, content):
        html_tag_pattern = re.compile(r'<[^>]+>')
        return bool(html_tag_pattern.search(content))

    # 发送邮件
    def send_email(self, subject, from_addr: str, to_addrs: Union[bytes, bytearray, str, None],
                  file_paths: List[str] = None, email_type: Literal['plain', 'html', 'file', 'multipart'] = 'plain',
                  content: str = None):
        if not self.__stmp:
            logging.error("SMTP 连接未建立")
            return

        if not to_addrs:
            logging.error("收件人地址为空")
            return

        if not content and email_type in ['text', 'html']:
            logging.error("邮件内容为空")
            return

        if email_type == 'plain' or email_type == 'html':
            msg = MIMEText(content, email_type, 'utf-8')
        elif email_type == 'file':
            msg = MIMEMultipart()
            for path in file_paths or []:
                with open(path, 'rb') as f:
                    m = MIMEText(f.read(), 'base64', 'utf-8')
                    m["Content-Type"] = 'application/octet-stream'
                    m["Content-Disposition"] = f'attachment; filename="{self.__handle_file_name(path)}"'
                    msg.attach(m)
        else:
            msg = MIMEMultipart()
            if content:
                msg.attach(MIMEText(content, 'plain' if not self.__is_html(content) else 'html', 'utf-8'))
            for path in file_paths or []:
                with open(path, 'rb') as f:
                    m = MIMEText(f.read(), 'base64', 'utf-8')
                    m["Content-Type"] = 'application/octet-stream'
                    m["Content-Disposition"] = f'attachment; filename="{self.__handle_file_name(path)}"'
                    msg.attach(m)

        msg['From'] = Header(from_addr)
        msg['To'] = Header(to_addrs)
        msg['Subject'] = Header(subject)

        try:
                # 发送邮件
                self.__stmp.sendmail(from_addr, to_addrs, msg.as_string())
                logging.info("邮件发送成功!")
        except Exception as e:
            logging.error(f"邮件发送失败！错误：{e}")



